package com.scs.application.core.utils;

import lombok.extern.slf4j.Slf4j;

import java.sql.PreparedStatement;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 命名参数
*/
@Slf4j
public class NamedParamSqlUtils {

    private Map<Integer, String> paramsMap = new HashMap<Integer, String>();


    public Map<Integer, String> getParamsMap() {
        return paramsMap;
    }

    public void emptyMap() {
        paramsMap.clear();
    }

    /**
     * 分析处理带命名参数的SQL语句。使用Map存储参数，然后将参数替换成?
     * @param sql
     * @return
     */
    public String parseSql(String sql) {
//        String regex = "(:(\\w+))";
        String regex = "(\\{\\{(\\w+)\\}\\})";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(sql);
        emptyMap();
        int idx = 1;
        while (m.find()) {
            //参数名称可能有重复，使用序号来做Key
            paramsMap.put(new Integer(idx++), m.group(2));
            //System.out.println(m.group(2));
        }
        String result = sql.replaceAll(regex, "?");
        return result;
    }

    /**
     * 使用参数值Map，填充pStat
     *
     * @param pStat
     * @param pMap  命名参数的值表，其中的值可以比较所需的参数多。
     * @return
     */
    public boolean fillParameters(PreparedStatement pStat, Map<String, Object> pMap) {
        boolean result = true;
        String paramName = null;
        Object paramValue = null;
        int idx = 1;
        for (java.util.Iterator<Map.Entry<Integer, String>> itr = paramsMap.entrySet().iterator(); itr.hasNext(); ) {
            Map.Entry<Integer, String> entry =  itr.next();
            paramName = entry.getValue();
            idx = entry.getKey();
            //不包含会返回null
            paramValue = pMap.get(paramName);
            try {
                //paramValue为null，会出错吗？需要测试
                pStat.setObject(idx, paramValue);
            } catch (Exception e) {
                log.error("填充参数出错，原因：" + e.getMessage());
                result = false;
            }
        }
        return result;
    }
}

